package com.huluobo.a2202kotlindouyindemo.utils

import android.animation.TypeEvaluator
import android.animation.ValueAnimator
import android.content.Context
import android.graphics.PointF
import android.util.AttributeSet
import android.util.Log
import android.view.animation.AccelerateInterpolator
import android.widget.ImageView
import android.widget.RelativeLayout

/**
 *  Created by LC on 2024/5/31.
 */
class BezierLineAnimView(context: Context, attributeSet: AttributeSet) : RelativeLayout(context, attributeSet) {
    private var resIds = arrayOf<Int>()
    fun setResIds(resId: Array<Int>) {
        resIds = resId
    }

    fun addFavor() {
        //1.创建出一个imageView,添加到当前布局上
        val imageView = ImageView(context)
        val index = Math.random() * resIds.size
        imageView.setImageResource(resIds[index.toInt()])

        val layoutParams = LayoutParams(200, 200)
        imageView.layoutParams = layoutParams
        addView(imageView)

        //2.定义起始点和控制点
        val width = measuredWidth
        val height = measuredHeight
        val offset = 100//当前view一半的大小

        //定义起始点
        val P0 = PointF((width / 2 - offset).toFloat(), height.toFloat())
        val P3 = PointF((width / 2 - offset).toFloat(), 0f)

        //定义控制点
//        val P1 = PointF((Math.random() * width).toFloat(), height / 3f * 2 - offset)
//        val P2 = PointF((Math.random() * width).toFloat(), height / 3f - offset)


        //定义控制点
        val P1 = PointF((Math.random() * width).toFloat() - offset, height / 3.0f * 2 - offset)
        val P2 = PointF((Math.random() * width).toFloat() - offset, height / 3.0f - offset)

        //3.定义属性动画
        val animator = ValueAnimator.ofObject(BezierTypeEvaluator2(P1, P2), P0, P3)
        animator.duration = 1200
        animator.interpolator = AccelerateInterpolator()
        animator.addUpdateListener {
            val pointF = it.animatedValue as PointF
            imageView.x = pointF.x
            imageView.y = pointF.y

            val f = it.animatedFraction
            imageView.alpha = 1 - f
        }
        animator.start()
    }

    //贝塞尔曲线的鉴别器,相当于一个公式(曲线公式)
    //P1 P2代表曲线拉伸的点
    class BezierTypeEvaluator(private var P1: PointF, private var P2: PointF) : TypeEvaluator<PointF> {

        override fun evaluate(f: Float, P0: PointF, P3: PointF): PointF {
            val P = PointF()
            //三阶贝塞尔曲线计算公式
            //计算x轴
            P.x =
                P0.x * (1 - f) * (1 - f) * (1 - f)
            +3 * P1.x * f * (1 - f) * (1 - f)
            +3 * P2.x * f * f * (1 - f)
            +P3.x * f * f * f
            P.y =
                P0.y * (1 - f) * (1 - f) * (1 - f)
            +3 * P1.y * f * (1 - f) * (1 - f)
            +3 * P2.y * f * f * (1 - f)
            +P3.y * f * f * f
            //三阶贝塞尔曲线移动公式
            //计算x轴


            //四阶贝塞尔曲线x点的移动轨迹
//            P.x = P0.x * (1 - f) * (1 - f) * (1 - f) * (1 - f)
//            +4 * P1.x * f * (1 - f) * (1 - f) * (1 - f)
//            +4 * P2.x * f * f * (1 - f) * (1 - f)
//            +4 * P3.x * f * f * f * (1 - f)
//            +P4.x * f * f * f * f

            //二阶贝塞尔曲线x点的移动轨迹
//            P.x = P0.x * (1 - f) * (1 - f)
//            +2 * P1.x * f * (1 - f)
//            +P2.x * f * f

            //一阶贝塞尔曲线x点的移动轨迹
//            P.x = P0.x * (1 - f)
//            +1 * P1.x * f
            Log.i("TagA", "px:${P.x},py:${P.y}")
            return P

        }

    }

    //贝塞尔曲线的鉴别器 相当于一个公式(曲线公式)
    internal class BezierTypeEvaluator2(
        var P1: PointF, //代表曲线拉伸的点
        var P2: PointF
    ) : TypeEvaluator<PointF> {

        override fun evaluate(f: Float, P0: PointF, P3: PointF): PointF {
            val P = PointF()
            //三阶贝塞尔曲线移动公式
            //计算x轴
            P.x =
                P0.x * (1 - f) * (1 - f) * (1 - f) + 3 * P1.x * f * (1 - f) * (1 - f) + 3 * P2.x * f * f * (1 - f) + P3.x * f * f * f
            P.y =
                P0.y * (1 - f) * (1 - f) * (1 - f) + 3 * P1.y * f * (1 - f) * (1 - f) + 3 * P2.y * f * f * (1 - f) + P3.y * f * f * f

//            //四阶贝塞尔曲线x点的移动轨迹
//            P.x = P0.x * (1 - f) * (1 - f) * (1 - f) * (1 - f)
//                    + 4 * P1.x * f * (1 - f) * (1 - f) * (1 - f)
//                    + 4 * P2.x * f * f * (1 - f) * (1 - f)
//                    + 4 * P3.x * f * f * f * (1 - f)
//                    + P4.x * f * f * f * f;
//
//            //二阶贝塞尔曲线
//            P.x = P0.x * (1 - f) * (1 - f)
//                    + 2 * P1.x * f * (1 - f)
//                    + 2 * P2.x * f * f;
//
//            //一阶贝塞尔曲线
//            P.x = P0.x * (1 - f)
//                    + 1 * P1.x * f
            return P
        }
    }
}